﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.ComponentModel;

namespace MyClub.Web.UI.WebControls
{
    /// <summary>
    /// 
    /// </summary>
    [ParseChildren(true)]
    [DefaultProperty("Descrimenator")]
    public class SwitchView: Control, INamingContainer
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SwitchView"/> class.
        /// </summary>
        public SwitchView()
        {
        }

        /// <summary>
        /// Gets or sets the type of the comparison.
        /// </summary>
        /// <value>The type of the comparison.</value>
        [PersistenceMode(PersistenceMode.Attribute)]
        public StringComparison ComparisonType 
        {
            get { return (StringComparison)(ViewState["ComparisonType"] ?? StringComparison.CurrentCultureIgnoreCase); }
            set { ViewState["ComparisonType"] = value; } 
        }

        /// <summary>
        /// Gets or sets the descriminator.
        /// </summary>
        /// <value>The descriminator.</value>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Descriminator", Justification = "Acoording to wikipedia this is the correct spelling")]
        [PersistenceMode(PersistenceMode.Attribute)]
        public string Descriminator 
        {
            get { return (string)ViewState["Descriminator"]; }
            set { ViewState["Descriminator"] = value; }
        }

        private readonly SwitchViewCaseCollection cases = new SwitchViewCaseCollection();

        /// <summary>
        /// Gets the cases.
        /// </summary>
        /// <value>The cases.</value>
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public SwitchViewCaseCollection Cases
        {
            get { return cases; }
        }

        /// <summary>
        /// Gets or sets the default template.
        /// </summary>
        /// <value>The default template.</value>
        [TemplateInstance(TemplateInstance.Multiple)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public ITemplate DefaultTemplate { get; set; }

        /// <summary>
        /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
        /// </summary>
        protected override void CreateChildControls()
        {
            Controls.Clear();

            CreateChildControlHierarchy(false);

            ChildControlsCreated = true;
        }

        /// <summary>
        /// Binds a data source to the invoked server control and all its child controls.
        /// </summary>
        public override void DataBind()
        {
            OnDataBinding(EventArgs.Empty);

            Controls.Clear();
            if (HasChildViewState)
                ClearChildViewState();

            CreateChildControlHierarchy(true);

            DataBindChildren();

            ChildControlsCreated = true;
        }

        /// <summary>
        /// Creates the child control hiearchy.
        /// </summary>
        /// <param name="dataBinding">if set to <c>true</c> [data binding].</param>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "dataBinding", Justification = "Might be used in a derived class")]
        protected void CreateChildControlHierarchy(bool dataBinding)
        {
            ITemplate template = GetCaseTemplate() ?? DefaultTemplate;

            if (template == null)
                return;

            template.InstantiateIn(this);
        }

        private ITemplate GetCaseTemplate()
        {
            var switchCase = cases.Where(c => string.Compare(Descriminator, c.Value, ComparisonType) == 0).FirstOrDefault();

            if (switchCase != null)
                return switchCase.GetTemplate(this);
            
            return null;
        }

        /// <summary>
        /// Restores view-state information from a previous page request that was saved by the <see cref="M:System.Web.UI.Control.SaveViewState"/> method.
        /// </summary>
        /// <param name="savedState">An <see cref="T:System.Object"/> that represents the control state to be restored.</param>
        protected override void LoadViewState(object savedState)
        {
            var viewState = (object[])savedState;
            base.LoadViewState(viewState[0]);
            (cases as IStateManager).LoadViewState(viewState[1]);
        }

        /// <summary>
        /// Saves any server control view-state changes that have occurred since the time the page was posted back to the server.
        /// </summary>
        /// <returns>
        /// Returns the server control's current view state. If there is no view state associated with the control, this method returns null.
        /// </returns>
        protected override object SaveViewState()
        {
            return new object[] {
                base.SaveViewState(),
                (cases as IStateManager).SaveViewState()
            };
        }
    }
}
